package com.yxinsur.imc.web.controller.business;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.yxinsur.imc.business.domain.ImcReportData;
import com.yxinsur.imc.business.domain.ImcReportTitle;
import com.yxinsur.imc.business.enums.IsDeletedEnum;
import com.yxinsur.imc.business.enums.OrderStepEnum;
import com.yxinsur.imc.business.enums.ReportTypeEnum;
import com.yxinsur.imc.business.form.*;
import com.yxinsur.imc.business.mapper.ImcReportDataMapper;
import com.yxinsur.imc.business.service.*;
import com.yxinsur.imc.business.vo.*;
import com.yxinsur.imc.common.annotation.Log;
import com.yxinsur.imc.common.core.controller.BaseController;
import com.yxinsur.imc.common.core.domain.AjaxResult;
import com.yxinsur.imc.common.core.page.TableDataInfo;
import com.yxinsur.imc.common.enums.BusinessType;
import com.yxinsur.imc.common.utils.DateUtils;
import com.yxinsur.imc.common.utils.SecurityUtils;
import com.yxinsur.imc.common.utils.poi.ExcelUtil;
import com.yxinsur.imc.system.service.ISysOrgService;
import com.yxinsur.imc.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 报表控制器Controller
 *
 * @author imc
 * @date 2021-05-28
 */
@Api(value="报表管理模块接口服务",tags={"11.报表管理模块接口服务"})
@RestController
@RequestMapping("/business/report")
public class ImcReportController extends BaseController
{
    @Autowired
    private IImcReportDataService imcReportDataService;
    @Autowired
    private IImcOrderService imcOrderService;
    @Autowired
    private IImcInsCatalogService imcInsCatalogService;
    @Autowired
    private IImcReportTitleService imcReportTitleService;
    @Autowired
    private ImcReportDataMapper imcReportDataMapper;

    /**
     * 个人业绩报表分页数据查询
     */
    @GetMapping("/achievement/list")
    @ApiOperation(value = "个人业绩报表分页数据查询")
    public TableDataInfo achievementList(ReportAchievementForm reportAchievementForm)
    {
        startPage();
        List<ImcReportData> list = this.imcReportDataMapper.selectListByReportType(reportAchievementForm,ReportTypeEnum.ACHIEVEMENT.getCode(), SecurityUtils.getTenantId());
        long totalSize = new PageInfo(list).getTotal();
        List<JSONObject> tableList = new ArrayList<>();
        for (ImcReportData reportData:list) {
            JSONObject json = JSONObject.parseObject(reportData.getReportData());
            json.put("date", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,reportData.getCreateTime()));
            tableList.add(json);
        }
        TableDataInfo tableDataInfo = getDataTable(tableList);
        tableDataInfo.setTotal(totalSize);
        return tableDataInfo;
    }

    /**
     * 个人业绩报表表头查询
     */
    @GetMapping("/achievement/titles")
    @ApiOperation(value = "个人业绩报表表头查询")
    public AjaxResult achievementTitle()
    {
        QueryWrapper<ImcReportTitle> titleQueryWrapper = new QueryWrapper<>();
        titleQueryWrapper.eq("is_deleted", IsDeletedEnum.N.getCode());
        titleQueryWrapper.eq("report_type", ReportTypeEnum.ACHIEVEMENT.getCode());
        List<ImcReportTitle> list = this.imcReportTitleService.list(titleQueryWrapper);
        if(list.size()>0){
            return AjaxResult.success(JSONObject.parseArray(list.get(0).getReportTitle()));
        }else{
            return AjaxResult.error("未有效配置该报表表头信息，请联系管理员");
        }
    }
    /**
     * 预收报表分页查询
     */
    @GetMapping("/advance/list")
    @ApiOperation(value = "预收报表分页查询")
    public TableDataInfo advanceList(ReportAdvanceForm reportAdvanceForm)
    {
        startPage();
        reportAdvanceForm.setType(ReportAdvanceForm.Type.ADVANCE_REPORT.getCode());
        List<ReportAdvanceVo> list = imcOrderService.selectAdvanceReportList(reportAdvanceForm);
        return getDataTable(list);
    }

    /**
     * 预收报表全量导出
     * @param reportAdvanceForm
     * @return
     */
    @GetMapping("/advance/AllExport")
    @ApiOperation(value = "预收报表全量导出")
    public void advanceAllExport(ReportAdvanceForm reportAdvanceForm, HttpServletRequest request, HttpServletResponse response) throws IOException {
        reportAdvanceForm.setType(ReportAdvanceForm.Type.ADVANCE_REPORT.getCode());
        List<ReportAdvanceExportVo> list = imcOrderService.advanceAllExport(reportAdvanceForm);
        ArrayList<ReportAdvanceExportVo> excelList = CollUtil.newArrayList(list);
        ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter();
        makeExcelTitle(writer);
        OutputStream out = response.getOutputStream();
        writer.write(excelList, true);
        if(CollectionUtils.isNotEmpty(list)){
            writer.autoSizeColumnAll();
        }

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("预收报表全量信息.xlsx", "UTF-8"));

        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    private void makeExcelTitle(ExcelWriter writer) {
        writer.addHeaderAlias("policyCode","保单号");
        writer.addHeaderAlias("proposalCode","投保单号");
        writer.addHeaderAlias("riskStatusCode","保单状态");
        writer.addHeaderAlias("brokerName","代理人姓名");
        writer.addHeaderAlias("brokerCode","服务代理人代码");
        writer.addHeaderAlias("brokerLevel","服务代理人职级");
        writer.addHeaderAlias("orgName","管理机构");
        writer.addHeaderAlias("teamName","直辖团队");
        writer.addHeaderAlias("suoxiaName","所辖团队");
        writer.addHeaderAlias("supplierName","供应商");
        writer.addHeaderAlias("insCode","险种代码");
        writer.addHeaderAlias("riskName","险种名称");
        writer.addHeaderAlias("applyDate","投保日期");
        writer.addHeaderAlias("insureDate","承保日期");
        writer.addHeaderAlias("effectiveDate","生效日期");
        writer.addHeaderAlias("payableDate","应缴日期");
        writer.addHeaderAlias("paymentDate","实缴日期");
        writer.addHeaderAlias("policyYear","保单年度");
        writer.addHeaderAlias("chargeIntervalEnum","缴费频率类型");
        writer.addHeaderAlias("chargePeriodEnum","缴费期间类型");
        writer.addHeaderAlias("chargePeriodValue","缴费期限");
        writer.addHeaderAlias("payNum","缴费期数");
        writer.addHeaderAlias("prem","首年保费（元）");
        writer.addHeaderAlias("payablePrem","应缴保费（元）");
        writer.addHeaderAlias("paymentPrem","实缴保费（元）");
        writer.addHeaderAlias("isFeeSettled","手续费状态");
        writer.addHeaderAlias("isCommPaid","佣金发放状态");
        writer.addHeaderAlias("standRate","折标率");
        writer.addHeaderAlias("standPrem","首年标保");
        writer.addHeaderAlias("commissionRate","佣金率");
        writer.addHeaderAlias("commission","佣金");
        writer.addHeaderAlias("feeRate","手续费率");
        writer.addHeaderAlias("baseFee","手续费");
        writer.addHeaderAlias("amount","险种基本保额");
        writer.addHeaderAlias("custAckDate","客户回执签收时间");
        writer.addHeaderAlias("revisitDate","客户回访日期");
        writer.addHeaderAlias("ackDate","回执录入日期");
        writer.addHeaderAlias("applicantName","投保人姓名");
        writer.addHeaderAlias("applicantGender","投保人性别");
        writer.addHeaderAlias("applicantOccName","投保人职业名称");
        writer.addHeaderAlias("applicantCertiType","投保人证件类型");
        writer.addHeaderAlias("applicantCertiCode","投保人证件号码");
        writer.addHeaderAlias("applicantBirthday","投保人出生日期");
        writer.addHeaderAlias("applicantCertiExpiryDate","投保人证件到期时间");
        writer.addHeaderAlias("applicantMobile","投保人联系方式");
        writer.addHeaderAlias("applicanthouseTel","投保人住宅电话");
        writer.addHeaderAlias("applicantProvince","投保人省");
        writer.addHeaderAlias("applicantCity","投保人市");
        writer.addHeaderAlias("applicantCounty","投保人区");
        writer.addHeaderAlias("applicantHomeAddr","投保人家庭地址");
        writer.addHeaderAlias("applicantMaritalStatus","投保人婚姻状况");
        writer.addHeaderAlias("applicantMailAddr","投保人通讯地址");
        writer.addHeaderAlias("applicantPostalcode","投保人邮政编码");
        writer.addHeaderAlias("applicantEmail","投保人邮箱");
        writer.addHeaderAlias("applicantIncome","投保人收入");
        writer.addHeaderAlias("applicantHeight","投保人身高");
        writer.addHeaderAlias("applicantWeight","投保人体重");
        writer.addHeaderAlias("applicantWorkUnit","投保人工作单位");
        writer.addHeaderAlias("applicantUnitAddr","投保人工作单位地址");

        writer.addHeaderAlias("insurantName","被保人姓名");
        writer.addHeaderAlias("insurantGender","被保人性别");
        writer.addHeaderAlias("insurantOccName","被保人职业名称");
        writer.addHeaderAlias("insurantCertiType","被保人证件类型");
        writer.addHeaderAlias("insurantCertiCode","被保人证件号码");
        writer.addHeaderAlias("insurantBirthday","被保人出生日期");
        writer.addHeaderAlias("insurantCertiExpiryDate","被保人证件到期时间");
        writer.addHeaderAlias("insurantMobile","被保人联系方式");
        writer.addHeaderAlias("insuranthouseTel","被保人住宅电话");
        writer.addHeaderAlias("insurantProvince","被保人省");
        writer.addHeaderAlias("insurantCity","被保人市");
        writer.addHeaderAlias("insurantCounty","被保人区");
        writer.addHeaderAlias("insurantHomeAddr","被保人家庭地址");
        writer.addHeaderAlias("insurantMaritalStatus","被保人婚姻状况");
        writer.addHeaderAlias("insurantMailAddr","被保人通讯地址");
        writer.addHeaderAlias("insurantPostalcode","被保人邮政编码");
        writer.addHeaderAlias("insurantEmail","被保人邮箱");
        writer.addHeaderAlias("insurantIncome","被保人收入");
        writer.addHeaderAlias("insurantHeight","被保人身高");
        writer.addHeaderAlias("insurantWeight","被保人体重");
        writer.addHeaderAlias("insurantWorkUnit","被保人工作单位");
        writer.addHeaderAlias("insurantUnitAddr","被保人工作单位地址");
        writer.addHeaderAlias("insurantRelationWithApplicant","被保人与投保人关系");

        writer.addHeaderAlias("favourName","受益人姓名");
        writer.addHeaderAlias("favourGender","受益人性别");
        writer.addHeaderAlias("favourOccName","受益人职业名称");
        writer.addHeaderAlias("favourCertiType","受益人证件类型");
        writer.addHeaderAlias("favourCertiCode","受益人证件号码");
        writer.addHeaderAlias("favourBirthday","受益人出生日期");
        writer.addHeaderAlias("favourCertiExpiryDate","受益人证件到期时间");
        writer.addHeaderAlias("favourMobile","受益人联系方式");
        writer.addHeaderAlias("favourhouseTel","受益人住宅电话");
        writer.addHeaderAlias("favourProvince","受益人省");
        writer.addHeaderAlias("favourCity","受益人市");
        writer.addHeaderAlias("favourCounty","受益人区");
        writer.addHeaderAlias("favourHomeAddr","受益人家庭地址");
        writer.addHeaderAlias("favourMaritalStatus","受益人婚姻状况");
        writer.addHeaderAlias("favourMailAddr","受益人通讯地址");
        writer.addHeaderAlias("favourPostalcode","受益人邮政编码");
        writer.addHeaderAlias("favourEmail","受益人邮箱");
        writer.addHeaderAlias("favourIncome","受益人收入");
        writer.addHeaderAlias("favourHeight","受益人身高");
        writer.addHeaderAlias("favourWeight","受益人体重");
        writer.addHeaderAlias("favourWorkUnit","受益人工作单位");
        writer.addHeaderAlias("favourUnitAddr","受益人工作单位地址");
        writer.addHeaderAlias("favourRelationWithApplicant","受益人与投保人关系");
        writer.addHeaderAlias("favourIsLegalBeneficiary","是否法定受益人");
        writer.addHeaderAlias("favourBenefitOrder","受益顺序");
        writer.addHeaderAlias("favourBenefitRate","受益比例");
        writer.addHeaderAlias("favourIsSameApplicant","是否同投保人");
        writer.addHeaderAlias("favourRelationWithInsurant","受益人与被保险人关系");

        writer.addHeaderAlias("bankAccName","银行户名");
        writer.addHeaderAlias("bankAccount","银行账号");
        writer.addHeaderAlias("bankName","银行名");
    }

    /**
     * 预收报表数据查询
     */
    @ApiOperation("预收报表导出数据查询")
    @GetMapping("/advance/export")
    public AjaxResult advanceExport(ReportAdvanceForm reportAdvanceForm)
    {
        reportAdvanceForm.setType(ReportAdvanceForm.Type.ADVANCE_REPORT.getCode());
        List<ReportAdvanceVo> list = imcOrderService.selectAdvanceReportList(reportAdvanceForm);
        ExcelUtil<ReportAdvanceVo> util = new ExcelUtil<ReportAdvanceVo>(ReportAdvanceVo.class);
        return util.exportExcel(list, "预收报表数据");
    }
    /**
     * 续期报表分页查询
     */
    @GetMapping("/renewal/list")
    @ApiOperation(value = "续期报表分页查询")
    public TableDataInfo renewalList(ReportAdvanceForm reportAdvanceForm)
    {
        startPage();
        reportAdvanceForm.setType(ReportAdvanceForm.Type.RENEWAL_REPORT.getCode());
        List<ReportAdvanceVo> list = imcOrderService.selectAdvanceReportList(reportAdvanceForm);
        return getDataTable(list);
    }
    /**
     * 预收报表数据查询
     */
    @ApiOperation("预收报表导出数据查询")
    @GetMapping("/renewal/export")
    public AjaxResult renewalExport(ReportAdvanceForm reportAdvanceForm)
    {
        reportAdvanceForm.setType(ReportAdvanceForm.Type.RENEWAL_REPORT.getCode());
        List<ReportAdvanceVo> list = imcOrderService.selectAdvanceReportList(reportAdvanceForm);
        ExcelUtil<ReportAdvanceVo> util = new ExcelUtil<ReportAdvanceVo>(ReportAdvanceVo.class);
        return util.exportExcel(list, "续期报表数据");
    }
    /**
     * 监管分类报表分页查询
     */
    @GetMapping("/catalog/list")
    @ApiOperation(value = "监管分类报表分页查询")
    public TableDataInfo catalogList(String year,Long orgId)
    {
        startPage();
        List<ReportInsCatalogVo> list = imcInsCatalogService.selectInsCatalogReportList(year,orgId);
        return getDataTable(list);
    }
    /**
     * 监管分类报表数据查询
     */
    @ApiOperation("监管分类报表导出数据查询")
    @GetMapping("/catalog/export")
    public AjaxResult catalogExport(String year,Long orgId)
    {
        List<ReportInsCatalogVo> list = imcInsCatalogService.selectInsCatalogReportList(year,orgId);
        ExcelUtil<ReportInsCatalogVo> util = new ExcelUtil<ReportInsCatalogVo>(ReportInsCatalogVo.class);
        return util.exportExcel(list, "监管分类报表数据");
    }

    //自保件查询
    // 入参：投保时间上下限  代理人姓名  是否自保件  保单号
    // 出参：保单号，机构名称，代理人姓名，投保人，被保人，直辖团队，保险公司，险种名称，缴费年期，首年保费，首年标保，保单状态，投保日期，承保日期，回执日期
    @GetMapping("/selfHold/list")
    @ApiOperation(value = "自保件报表查询")
    public TableDataInfo selfHoldList(OrderSelfHoldForm orderSelfHoldForm){
        startPage();
        List<OrderSelfHoldVo> list = imcOrderService.selfHoldList(orderSelfHoldForm);
        return getDataTable(list);
    }

    //批量标记自保件
    //传入ids 批量修改自保件 Y 标记为自保件 N 标记为非自保件
    /**
     * 保单批改
     */
    @ApiOperation("标记自保件")
    @Log(title = "标记自保件", businessType = BusinessType.UPDATE)
    @PostMapping("/selfHold/update/{isSelf}")
    public AjaxResult updateSelfHold(@RequestBody List<Long> idList,@PathVariable("isSelf") String isSelf){
        imcOrderService.updateSelfHold(idList,isSelf);
        return AjaxResult.success();
    }

    //自保件报表导出

    /**
     * 自保件报表导出
     */
    @ApiOperation("自保件报表导出")
    @GetMapping("/selfHold/export")
    public AjaxResult selfHoldExport(OrderSelfHoldForm orderSelfHoldForm) {
        List<OrderSelfHoldVo> list = imcOrderService.selfHoldList(orderSelfHoldForm);
        ExcelUtil<OrderSelfHoldVo> util = new ExcelUtil<OrderSelfHoldVo>(OrderSelfHoldVo.class);
        return util.exportExcel(list, "自保件报表导出");
    }
}
